<!DOCTYPE html>
<html lang="en-US">
  <head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width,initial-scale=1">
    <title>Vue 源码的三大核心 | TBlog</title>
    <meta name="description" content="TBlog with vitePress">
    <link rel="stylesheet" href="/interview/assets/style.9156a4ed.css">
    <link rel="modulepreload" href="/interview/assets/Home.b86443e2.js">
    <link rel="modulepreload" href="/interview/assets/app.49accf37.js">
    <link rel="modulepreload" href="/interview/assets/Vue_reactive.md.206c8e46.lean.js">
    <link rel="modulepreload" href="/interview/assets/app.49accf37.js">
    <link rel="icon" href="/favicon.ico">
    <meta name="twitter:title" content="Vue 源码的三大核心 | TBlog">
    <meta property="og:title" content="Vue 源码的三大核心 | TBlog">
  </head>
  <body>
    <div id="app"><!--[--><div class="theme"><header class="nav-bar" data-v-7161a24b><div class="sidebar-button" data-v-7161a24b><svg class="icon" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" role="img" viewBox="0 0 448 512"><path fill="currentColor" d="M436 124H12c-6.627 0-12-5.373-12-12V80c0-6.627 5.373-12 12-12h424c6.627 0 12 5.373 12 12v32c0 6.627-5.373 12-12 12zm0 160H12c-6.627 0-12-5.373-12-12v-32c0-6.627 5.373-12 12-12h424c6.627 0 12 5.373 12 12v32c0 6.627-5.373 12-12 12zm0 160H12c-6.627 0-12-5.373-12-12v-32c0-6.627 5.373-12 12-12h424c6.627 0 12 5.373 12 12v32c0 6.627-5.373 12-12 12z" class></path></svg></div><a class="nav-bar-title" href="/interview/" aria-label="TBlog, back to home" data-v-7161a24b data-v-4a583abe><!----> TBlog</a><div class="flex-grow" data-v-7161a24b></div><div class="nav" data-v-7161a24b><nav class="nav-links" data-v-7161a24b data-v-15acbf05><!--[--><div class="item" data-v-15acbf05><div class="nav-link" data-v-15acbf05 data-v-641633f9><a class="item isExternal" href="http://101.43.7.188:66" target="_blank" rel="noopener noreferrer" data-v-641633f9>Music <svg class="icon outbound" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" x="0px" y="0px" viewbox="0 0 100 100" width="15" height="15" data-v-641633f9><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path><polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg></a></div></div><div class="item" data-v-15acbf05><div class="nav-link" data-v-15acbf05 data-v-641633f9><a class="item isExternal" href="http://101.43.7.188:80" target="_blank" rel="noopener noreferrer" data-v-641633f9>CMC <svg class="icon outbound" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" x="0px" y="0px" viewbox="0 0 100 100" width="15" height="15" data-v-641633f9><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path><polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg></a></div></div><div class="item" data-v-15acbf05><div class="nav-link" data-v-15acbf05 data-v-641633f9><a class="item isExternal" href="https://juejin.cn/user/2163479676978734/posts" target="_blank" rel="noopener noreferrer" data-v-641633f9>掘金 <svg class="icon outbound" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" x="0px" y="0px" viewbox="0 0 100 100" width="15" height="15" data-v-641633f9><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path><polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg></a></div></div><div class="item" data-v-15acbf05><div class="nav-link" data-v-15acbf05 data-v-641633f9><a class="item isExternal" href="https://gitee.com/tu_zhiwei98" target="_blank" rel="noopener noreferrer" data-v-641633f9>Gitee <svg class="icon outbound" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" x="0px" y="0px" viewbox="0 0 100 100" width="15" height="15" data-v-641633f9><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path><polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg></a></div></div><!--]--><!----><!----></nav></div><!--[--><!--]--></header><aside class="sidebar" data-v-6b49cdcd><nav class="nav-links nav" data-v-6b49cdcd data-v-15acbf05><!--[--><div class="item" data-v-15acbf05><div class="nav-link" data-v-15acbf05 data-v-641633f9><a class="item isExternal" href="http://101.43.7.188:66" target="_blank" rel="noopener noreferrer" data-v-641633f9>Music <svg class="icon outbound" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" x="0px" y="0px" viewbox="0 0 100 100" width="15" height="15" data-v-641633f9><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path><polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg></a></div></div><div class="item" data-v-15acbf05><div class="nav-link" data-v-15acbf05 data-v-641633f9><a class="item isExternal" href="http://101.43.7.188:80" target="_blank" rel="noopener noreferrer" data-v-641633f9>CMC <svg class="icon outbound" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" x="0px" y="0px" viewbox="0 0 100 100" width="15" height="15" data-v-641633f9><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path><polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg></a></div></div><div class="item" data-v-15acbf05><div class="nav-link" data-v-15acbf05 data-v-641633f9><a class="item isExternal" href="https://juejin.cn/user/2163479676978734/posts" target="_blank" rel="noopener noreferrer" data-v-641633f9>掘金 <svg class="icon outbound" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" x="0px" y="0px" viewbox="0 0 100 100" width="15" height="15" data-v-641633f9><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path><polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg></a></div></div><div class="item" data-v-15acbf05><div class="nav-link" data-v-15acbf05 data-v-641633f9><a class="item isExternal" href="https://gitee.com/tu_zhiwei98" target="_blank" rel="noopener noreferrer" data-v-641633f9>Gitee <svg class="icon outbound" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" x="0px" y="0px" viewbox="0 0 100 100" width="15" height="15" data-v-641633f9><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path><polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg></a></div></div><!--]--><!----><!----></nav><!--[--><!--]--><ul class="sidebar-links" data-v-6b49cdcd><!--[--><li class="sidebar-link"><p class="sidebar-link-item">Vue3.2X</p><ul class="sidebar-links"><li class="sidebar-link"><a class="sidebar-link-item" href="/interview/Vue/">基本语法&amp;使用</a><!----></li><li class="sidebar-link"><a class="sidebar-link-item" href="/interview/Vue/VueX">VueX4.x</a><!----></li><li class="sidebar-link"><a class="sidebar-link-item" href="/interview/Vue/Router">Router4.x</a><!----></li><li class="sidebar-link"><p class="sidebar-link-item">部分源码解析</p><ul class="sidebar-links"><li class="sidebar-link"><a class="sidebar-link-item active" href="/interview/Vue/reactive">响应式系统</a><ul class="sidebar-links"><li class="sidebar-link"><a class="sidebar-link-item" href="#vue-源码的三大核心">Vue 源码的三大核心</a><!----></li><li class="sidebar-link"><a class="sidebar-link-item" href="#渲染系统的实现">渲染系统的实现</a><ul class="sidebar-links"><li class="sidebar-link"><a class="sidebar-link-item" href="#mout-函数">Mout 函数</a><!----></li><li class="sidebar-link"><a class="sidebar-link-item" href="#patch-函数">patch 函数</a><!----></li></ul></li><li class="sidebar-link"><a class="sidebar-link-item" href="#响应式系统">响应式系统</a><ul class="sidebar-links"><li class="sidebar-link"><a class="sidebar-link-item" href="#响应式的思想">响应式的思想::</a><!----></li></ul></li><li class="sidebar-link"><a class="sidebar-link-item" href="#vue2-跟-vue3-的响应式区别">Vue2 跟 Vue3 的响应式区别</a><ul class="sidebar-links"><li class="sidebar-link"><a class="sidebar-link-item" href="#object-definepropery">object.definePropery</a><!----></li><li class="sidebar-link"><a class="sidebar-link-item" href="#proxy">Proxy</a><!----></li></ul></li><li class="sidebar-link"><a class="sidebar-link-item" href="#响应式基础-reactive-的核心源码">响应式基础 reactive 的核心源码</a><!----></li></ul></li><li class="sidebar-link"><a class="sidebar-link-item" href="/interview/Vue/source/Watch">Watch</a><!----></li><li class="sidebar-link"><a class="sidebar-link-item" href="/interview/Vue/source/nextTick">nextTick</a><!----></li></ul></li></ul></li><li class="sidebar-link"><p class="sidebar-link-item">WebPack</p><ul class="sidebar-links"><li class="sidebar-link"><a class="sidebar-link-item" href="/interview/WebPack/">基础配置</a><!----></li><li class="sidebar-link"><a class="sidebar-link-item" href="/interview/WebPack/optimize">优化方案</a><!----></li><li class="sidebar-link"><a class="sidebar-link-item" href="/interview/WebPack/common">常见的Loader以及Plugin</a><!----></li><li class="sidebar-link"><a class="sidebar-link-item" href="/interview/WebPack/custom">自定义Loader以及Plugin</a><!----></li><li class="sidebar-link"><a class="sidebar-link-item" href="/interview/WebPack/advanced">手写简单的MY_Webpack</a><!----></li></ul></li><li class="sidebar-link"><p class="sidebar-link-item">Javascript</p><ul class="sidebar-links"><li class="sidebar-link"><a class="sidebar-link-item" href="/interview/Javascript/">基本语法</a><!----></li><li class="sidebar-link"><a class="sidebar-link-item" href="/interview/Javascript/advanced">高级语法</a><!----></li></ul></li><li class="sidebar-link"><p class="sidebar-link-item">TypeScript</p><ul class="sidebar-links"><li class="sidebar-link"><a class="sidebar-link-item" href="/interview/TypeScript/">基本语法</a><!----></li><li class="sidebar-link"><a class="sidebar-link-item" href="/interview/TypeScript/combat">业务实战</a><!----></li><li class="sidebar-link"><a class="sidebar-link-item" href="/interview/TypeScript/advanced">高阶使用</a><!----></li></ul></li><li class="sidebar-link"><p class="sidebar-link-item">浏览器相关</p><ul class="sidebar-links"><li class="sidebar-link"><a class="sidebar-link-item" href="/interview/Browser/">基本原理</a><!----></li><li class="sidebar-link"><a class="sidebar-link-item" href="/interview/Browser/plugin">浏览器插件</a><!----></li><li class="sidebar-link"><a class="sidebar-link-item" href="/interview/Browser/advanced">深入原理</a><!----></li></ul></li><li class="sidebar-link"><p class="sidebar-link-item">计算机网络</p><ul class="sidebar-links"><li class="sidebar-link"><a class="sidebar-link-item" href="/interview/Network/">计算机网络</a><!----></li><li class="sidebar-link"><a class="sidebar-link-item" href="/interview/Network/security">前端安全</a><!----></li></ul></li><li class="sidebar-link"><p class="sidebar-link-item">HTML/CSS</p><ul class="sidebar-links"><li class="sidebar-link"><a class="sidebar-link-item" href="/interview/CSS/">CSS</a><!----></li><li class="sidebar-link"><a class="sidebar-link-item" href="/interview/HTML/">HTML</a><!----></li></ul></li><li class="sidebar-link"><p class="sidebar-link-item">Vite2.X</p><ul class="sidebar-links"><li class="sidebar-link"><a class="sidebar-link-item" href="/interview/Vite/">基础配置</a><!----></li><li class="sidebar-link"><a class="sidebar-link-item" href="/interview/Vite/optimize">原理以及优化</a><!----></li></ul></li><li class="sidebar-link"><p class="sidebar-link-item">Node</p><ul class="sidebar-links"><li class="sidebar-link"><a class="sidebar-link-item" href="/interview/Node/">基本知识</a><!----></li><li class="sidebar-link"><a class="sidebar-link-item" href="/interview/Node/pit">踩坑记录</a><!----></li></ul></li><li class="sidebar-link"><p class="sidebar-link-item">其他前端工具</p><ul class="sidebar-links"><li class="sidebar-link"><a class="sidebar-link-item" href="/interview/Git/">Git</a><!----></li><li class="sidebar-link"><a class="sidebar-link-item" href="/interview/Jenkins/">Jenkins</a><!----></li><li class="sidebar-link"><a class="sidebar-link-item" href="/interview/npm/">包管理工具</a><!----></li></ul></li><li class="sidebar-link"><p class="sidebar-link-item">踩坑记录以及经验</p><ul class="sidebar-links"><li class="sidebar-link"><a class="sidebar-link-item" href="/interview/Pit/">踩坑</a><!----></li><li class="sidebar-link"><a class="sidebar-link-item" href="/interview/solution/">一些解决方案</a><!----></li></ul></li><li class="sidebar-link"><p class="sidebar-link-item">面经</p><ul class="sidebar-links"><li class="sidebar-link"><a class="sidebar-link-item" href="/interview/Interview/">xxx面试</a><!----></li><li class="sidebar-link"><a class="sidebar-link-item" href="/interview/Interview/two">xxX面试</a><!----></li></ul></li><li class="sidebar-link"><p class="sidebar-link-item">个人学习历程</p><ul class="sidebar-links"><li class="sidebar-link"><a class="sidebar-link-item" href="/interview/Myself/">个人情况说明</a><!----></li><li class="sidebar-link"><a class="sidebar-link-item" href="/interview/Myself/pre">入行工作前</a><!----></li><li class="sidebar-link"><a class="sidebar-link-item" href="/interview/Myself/one">工作第一年</a><!----></li></ul></li><!--]--></ul><!--[--><!--]--></aside><!-- TODO: make this button accessible --><div class="sidebar-mask"></div><main class="page" data-v-7eddb2c4><div class="container" data-v-7eddb2c4><!--[--><!--]--><div style="position:relative;" class="content" data-v-7eddb2c4><div><p>reactivemini-vue 的 简单实现</p><h2 id="vue-源码的三大核心"><a class="header-anchor" href="#vue-源码的三大核心" aria-hidden="true">#</a> Vue 源码的三大核心</h2><ul><li><p>​ Compiler 模块: 编译模板系统</p></li><li><p>​ Runtime 模块: 也是 Renderer 模块, 是真正的渲染模块</p></li><li><p>​ Reactive 模块: 响应式系统</p></li></ul><p>虚拟 DOM 的优势</p><ol><li>可以抽象成虚拟节点 VNode,方便操作 er</li><li>直接操作 DON 有很多限制,可以利用 js 来操作</li><li>可以实现跨平台,也可以开发属于自己的渲染器</li></ol><p>虚拟 DOM 的渲染过程</p><div class="language-html"><pre><code>template
<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>div</span><span class="token punctuation">&gt;</span></span>TUTU<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>div</span><span class="token punctuation">&gt;</span></span>
通过compile编译器讲template转换成 render function(渲染函数) ----&gt;VNode VNode
render function 通过 renderer 函数 也就是h 函数 转换成虚拟节点 VNode
通过渲染器渲染成真实的元素 ------&gt; 真实元素 真实元素 ----&gt; 被浏览器解析
</code></pre></div><p>实现 supMini-Vue</p><ul><li>渲染系统模块 runtime &gt;&gt; VNode &gt;&gt;真实 DOM</li><li>可响应式系统模块 reactive()</li><li>应用程序入口模块 createapp( ).mount( )</li></ul><p>在项目部署之后 是没有 .vue &gt;&gt; @vue/compiler - sfc 这部分代码的 (编译器)</p><h2 id="渲染系统的实现"><a class="header-anchor" href="#渲染系统的实现" aria-hidden="true">#</a> 渲染系统的实现</h2><p>包含三个功能</p><ol><li>h 函数, 用于返回一个 VNode 对象</li><li>mount 函数, 将 VNode 挂载到 DOM 上</li><li>patch 函数 用于新旧 VNode 进行对比, 决定如何处理 VNode</li></ol><div class="language-javascript"><pre><code><span class="token comment">// h函数接受三个参数  第一个参数 标签&#39;div&#39;  第二个参数 props   第三个参数  一些子节点[children]</span>
<span class="token keyword">const</span> vnode <span class="token operator">=</span> <span class="token function">h</span><span class="token punctuation">(</span><span class="token string">&quot;div&quot;</span><span class="token punctuation">,</span> <span class="token punctuation">{</span> <span class="token keyword">class</span><span class="token operator">:</span> <span class="token string">&quot;eason&quot;</span> <span class="token punctuation">}</span><span class="token punctuation">,</span> <span class="token punctuation">[</span>
  <span class="token function">h</span><span class="token punctuation">(</span><span class="token string">&quot;h2&quot;</span><span class="token punctuation">,</span> <span class="token keyword">null</span><span class="token punctuation">,</span> <span class="token string">&quot;当前歌曲: 100&quot;</span><span class="token punctuation">)</span><span class="token punctuation">,</span>
  <span class="token function">h</span><span class="token punctuation">(</span><span class="token string">&quot;button&quot;</span><span class="token punctuation">,</span> <span class="token punctuation">{</span> <span class="token function-variable function">onclick</span><span class="token operator">:</span> <span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span><span class="token punctuation">}</span> <span class="token punctuation">}</span><span class="token punctuation">,</span> <span class="token string">&quot;+1&quot;</span><span class="token punctuation">)</span><span class="token punctuation">,</span>
  <span class="token function">h</span><span class="token punctuation">(</span><span class="token string">&quot;h3&quot;</span><span class="token punctuation">,</span> <span class="token keyword">null</span><span class="token punctuation">,</span> <span class="token punctuation">[</span>
    <span class="token function">h</span><span class="token punctuation">(</span><span class="token string">&quot;h3&quot;</span><span class="token punctuation">,</span> <span class="token keyword">null</span><span class="token punctuation">,</span> <span class="token string">&quot;我是第三层vnode1&quot;</span><span class="token punctuation">)</span><span class="token punctuation">,</span>
    <span class="token function">h</span><span class="token punctuation">(</span><span class="token string">&quot;h3&quot;</span><span class="token punctuation">,</span> <span class="token keyword">null</span><span class="token punctuation">,</span> <span class="token string">&quot;我是第三层vnode2&quot;</span><span class="token punctuation">)</span><span class="token punctuation">,</span>
    <span class="token function">h</span><span class="token punctuation">(</span><span class="token string">&quot;h3&quot;</span><span class="token punctuation">,</span> <span class="token keyword">null</span><span class="token punctuation">,</span> <span class="token punctuation">[</span><span class="token function">h</span><span class="token punctuation">(</span><span class="token string">&quot;h4&quot;</span><span class="token punctuation">,</span> <span class="token keyword">null</span><span class="token punctuation">,</span> <span class="token string">&quot;我是第四层vnode&quot;</span><span class="token punctuation">)</span><span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">,</span>
  <span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">,</span>
<span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>vnode<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token comment">/////////////////////////////////////////////////////////////////////////////////</span>
<span class="token function">setTimeout</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">=&gt;</span> <span class="token punctuation">{</span>
  <span class="token comment">// 创建一个新 VNode  将两个VNode 进行diff 算法</span>
  <span class="token keyword">const</span> vnode1 <span class="token operator">=</span> <span class="token function">h</span><span class="token punctuation">(</span><span class="token string">&quot;h2&quot;</span><span class="token punctuation">,</span> <span class="token punctuation">{</span> <span class="token keyword">class</span><span class="token operator">:</span> <span class="token string">&quot;shall we talk&quot;</span> <span class="token punctuation">}</span><span class="token punctuation">,</span> <span class="token punctuation">[</span>
    <span class="token function">h</span><span class="token punctuation">(</span><span class="token string">&quot;h2&quot;</span><span class="token punctuation">,</span> <span class="token keyword">null</span><span class="token punctuation">,</span> <span class="token string">&quot;shall we talk&quot;</span><span class="token punctuation">)</span><span class="token punctuation">,</span>
    <span class="token function">h</span><span class="token punctuation">(</span><span class="token string">&quot;button&quot;</span><span class="token punctuation">,</span> <span class="token punctuation">{</span> <span class="token function-variable function">onclick</span><span class="token operator">:</span> <span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span><span class="token punctuation">}</span> <span class="token punctuation">}</span><span class="token punctuation">,</span> <span class="token string">&quot;++1&quot;</span><span class="token punctuation">)</span><span class="token punctuation">,</span>
  <span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
  <span class="token function">patch</span><span class="token punctuation">(</span>vnode<span class="token punctuation">,</span> vnode1<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span><span class="token punctuation">,</span> <span class="token number">3000</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token function">mount</span><span class="token punctuation">(</span>vnode<span class="token punctuation">,</span> document<span class="token punctuation">.</span><span class="token function">querySelector</span><span class="token punctuation">(</span><span class="token string">&quot;#tutu&quot;</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token comment">/////////////////////////////////////////////////////////////////////////////////</span>
<span class="token comment">//    vnode 就是一个树结构的javascript对象 //</span>
<span class="token keyword">const</span> <span class="token function-variable function">h</span> <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token parameter">tag<span class="token punctuation">,</span> props<span class="token punctuation">,</span> children</span><span class="token punctuation">)</span> <span class="token operator">=&gt;</span> <span class="token punctuation">{</span>
  <span class="token keyword">return</span> <span class="token punctuation">{</span>
    tag<span class="token punctuation">,</span>
    props<span class="token punctuation">,</span>
    children<span class="token punctuation">,</span>
  <span class="token punctuation">}</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span><span class="token punctuation">;</span>
<span class="token comment">////////////////////////////////////////////////////////////////////////////////</span>
</code></pre></div><p>打印出的 VNode 结构</p><img src="/interview/assets/vnode结构.e2f7a6e2.png" style="zoom:100%;"><h3 id="mout-函数"><a class="header-anchor" href="#mout-函数" aria-hidden="true">#</a> Mout 函数</h3><div class="language-javascript"><pre><code><span class="token comment">// 我们需要拿到  vnode 挂载到真实 DOM 上 也就是我们这里的 &lt;div id=&quot;tutu&quot;&gt; &lt;/div&gt;</span>
<span class="token keyword">const</span> <span class="token function-variable function">mount</span> <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token parameter">vnode<span class="token punctuation">,</span> container</span><span class="token punctuation">)</span> <span class="token operator">=&gt;</span> <span class="token punctuation">{</span>
  <span class="token comment">// node  --&gt;element</span>
  <span class="token comment">// 先创建出了真实的元素,并在vnode上保留 这个真实 DOM</span>
  <span class="token keyword">const</span> el <span class="token operator">=</span> <span class="token punctuation">(</span>vnode<span class="token punctuation">.</span>el <span class="token operator">=</span> document<span class="token punctuation">.</span><span class="token function">createElement</span><span class="token punctuation">(</span>vnode<span class="token punctuation">.</span>tag<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>

  <span class="token comment">// 处理props</span>
  <span class="token keyword">if</span> <span class="token punctuation">(</span>vnode<span class="token punctuation">.</span>props<span class="token punctuation">)</span> <span class="token punctuation">{</span>
    <span class="token keyword">for</span> <span class="token punctuation">(</span><span class="token keyword">const</span> key <span class="token keyword">in</span> vnode<span class="token punctuation">.</span>props<span class="token punctuation">)</span> <span class="token punctuation">{</span>
      <span class="token keyword">const</span> value <span class="token operator">=</span> vnode<span class="token punctuation">.</span>props<span class="token punctuation">[</span>key<span class="token punctuation">]</span><span class="token punctuation">;</span>
      <span class="token comment">// 这里是对于 props 是为函数的情况进行处理</span>
      <span class="token keyword">if</span> <span class="token punctuation">(</span>key<span class="token punctuation">.</span><span class="token function">startsWith</span><span class="token punctuation">(</span><span class="token string">&quot;on&quot;</span><span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
        el<span class="token punctuation">.</span><span class="token function">addEventListener</span><span class="token punctuation">(</span>key<span class="token punctuation">.</span><span class="token function">slice</span><span class="token punctuation">(</span><span class="token number">2</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">toLocaleLowerCase</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">,</span> value<span class="token punctuation">)</span><span class="token punctuation">;</span>
      <span class="token punctuation">}</span> <span class="token keyword">else</span> <span class="token punctuation">{</span>
        el<span class="token punctuation">.</span><span class="token function">setAttribute</span><span class="token punctuation">(</span>key<span class="token punctuation">,</span> value<span class="token punctuation">)</span><span class="token punctuation">;</span>
      <span class="token punctuation">}</span>
    <span class="token punctuation">}</span>
  <span class="token punctuation">}</span>
  <span class="token comment">// 处理 子节点   这里只对于 字符串跟数组类型进行了处理</span>
  <span class="token keyword">if</span> <span class="token punctuation">(</span>vnode<span class="token punctuation">.</span>children<span class="token punctuation">)</span> <span class="token punctuation">{</span>
    <span class="token comment">//   数组情况</span>
    <span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token keyword">typeof</span> vnode<span class="token punctuation">.</span>children <span class="token operator">!==</span> <span class="token string">&quot;string&quot;</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
      vnode<span class="token punctuation">.</span>children<span class="token punctuation">.</span><span class="token function">forEach</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token parameter">item</span><span class="token punctuation">)</span> <span class="token operator">=&gt;</span> <span class="token punctuation">{</span>
        <span class="token comment">// 因为这里的  [children] 数组里 又是一个个h()函数</span>
        <span class="token comment">// 所以进行 递归  对 item 里面进行mout处理 此时挂载的是当前 VNode 元素上</span>
        <span class="token function">mount</span><span class="token punctuation">(</span>item<span class="token punctuation">,</span> el<span class="token punctuation">)</span><span class="token punctuation">;</span>
      <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token punctuation">}</span> <span class="token keyword">else</span> <span class="token punctuation">{</span>
      <span class="token comment">//  字符串情况</span>
      el<span class="token punctuation">.</span>textContent <span class="token operator">=</span> vnode<span class="token punctuation">.</span>children<span class="token punctuation">;</span>
    <span class="token punctuation">}</span>
  <span class="token punctuation">}</span>
  <span class="token comment">// 将 el 挂载到container 上</span>
  container<span class="token punctuation">.</span><span class="token function">appendChild</span><span class="token punctuation">(</span>el<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span><span class="token punctuation">;</span>
</code></pre></div><h3 id="patch-函数"><a class="header-anchor" href="#patch-函数" aria-hidden="true">#</a> patch 函数</h3><h4 id="_1-首先-判断下-tag-是否相同"><a class="header-anchor" href="#_1-首先-判断下-tag-是否相同" aria-hidden="true">#</a> 1: 首先 判断下 tag 是否相同</h4><div class="language-javascript"><pre><code><span class="token comment">// 传递进来两个VNode</span>
<span class="token keyword">const</span> <span class="token function-variable function">patch</span> <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token parameter">n1<span class="token punctuation">,</span> n2</span><span class="token punctuation">)</span> <span class="token operator">=&gt;</span> <span class="token punctuation">{</span>
  <span class="token keyword">if</span> <span class="token punctuation">(</span> n1<span class="token punctuation">.</span>tag <span class="token operator">!==</span> n2<span class="token punctuation">.</span>tag<span class="token punctuation">)</span> <span class="token punctuation">{</span>
    <span class="token comment">//  tag不同的话就  移除 旧 VNode 的父元素</span>
    <span class="token keyword">const</span> n1ElParent <span class="token operator">=</span> n1<span class="token punctuation">.</span>el<span class="token punctuation">.</span>parentElement<span class="token punctuation">;</span>
    n1ElParent<span class="token punctuation">.</span><span class="token function">removeChild</span><span class="token punctuation">(</span>n1<span class="token punctuation">.</span>el<span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token comment">//  将 新 VNode 挂在 n1的父元素上</span>
    <span class="token function">mount</span><span class="token punctuation">(</span>n2<span class="token punctuation">,</span>n1ElParent<span class="token punctuation">)</span>
  <span class="token punctuation">}</span>
</code></pre></div><h4 id="_2-然后进行-对-props-的处理"><a class="header-anchor" href="#_2-然后进行-对-props-的处理" aria-hidden="true">#</a> 2: 然后进行 对 props 的处理</h4><div class="language-javascript"><pre><code><span class="token keyword">else</span> <span class="token punctuation">{</span>
    <span class="token comment">//取出 element 对象 并且在 n2 中进行保存</span>
    <span class="token keyword">const</span> el <span class="token operator">=</span> n2<span class="token punctuation">.</span>el <span class="token operator">=</span> n1<span class="token punctuation">.</span>el
    <span class="token comment">// 2:   处理props</span>
    <span class="token keyword">const</span> oldProps <span class="token operator">=</span> n1<span class="token punctuation">.</span>props <span class="token operator">||</span> <span class="token punctuation">{</span><span class="token punctuation">}</span>
    <span class="token keyword">const</span> newProps <span class="token operator">=</span> n2<span class="token punctuation">.</span>props <span class="token operator">||</span> <span class="token punctuation">{</span><span class="token punctuation">}</span>
    <span class="token comment">//  获取所有的 newProps</span>
    <span class="token keyword">for</span> <span class="token punctuation">(</span><span class="token keyword">const</span> key <span class="token keyword">in</span> newProps<span class="token punctuation">)</span> <span class="token punctuation">{</span>
      <span class="token keyword">const</span> oldValue <span class="token operator">=</span> oldProps<span class="token punctuation">[</span>key<span class="token punctuation">]</span>
      <span class="token keyword">const</span> newValue <span class="token operator">=</span> newProps<span class="token punctuation">[</span>key<span class="token punctuation">]</span>
      <span class="token keyword">if</span> <span class="token punctuation">(</span> newValue <span class="token operator">!==</span> oldValue <span class="token punctuation">)</span> <span class="token punctuation">{</span>
          <span class="token comment">// 当props 为 onXxxx类型事件的时候的处理</span>
        <span class="token keyword">if</span> <span class="token punctuation">(</span> key<span class="token punctuation">.</span><span class="token function">startsWith</span><span class="token punctuation">(</span><span class="token string">&quot;on&quot;</span><span class="token punctuation">)</span> <span class="token punctuation">)</span> <span class="token punctuation">{</span>
            <span class="token comment">//  增加监听事件 addEventListener()函数需要 传入 事件名称 , 以及对应的value</span>
          el<span class="token punctuation">.</span><span class="token function">addEventListener</span><span class="token punctuation">(</span>key<span class="token punctuation">.</span><span class="token function">slice</span><span class="token punctuation">(</span><span class="token number">2</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">toLocaleLowerCase</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">,</span> newValue<span class="token punctuation">)</span>
        <span class="token punctuation">}</span> <span class="token keyword">else</span> <span class="token punctuation">{</span>
          el<span class="token punctuation">.</span><span class="token function">setAttribute</span><span class="token punctuation">(</span>key<span class="token punctuation">,</span> newValue<span class="token punctuation">)</span>
        <span class="token punctuation">}</span>
      <span class="token punctuation">}</span>
    <span class="token punctuation">}</span>
    <span class="token comment">// 删除旧的props</span>
    <span class="token keyword">for</span> <span class="token punctuation">(</span><span class="token keyword">const</span> key <span class="token keyword">in</span> oldProps<span class="token punctuation">)</span> <span class="token punctuation">{</span>
      <span class="token keyword">if</span> <span class="token punctuation">(</span>key<span class="token punctuation">.</span><span class="token function">startsWith</span><span class="token punctuation">(</span><span class="token string">&quot;on&quot;</span><span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
          <span class="token comment">// 对事件监听的判断</span>
        <span class="token keyword">const</span> value <span class="token operator">=</span> oldProps<span class="token punctuation">[</span>key<span class="token punctuation">]</span><span class="token punctuation">;</span>
        el<span class="token punctuation">.</span><span class="token function">removeEventListener</span><span class="token punctuation">(</span>key<span class="token punctuation">.</span><span class="token function">slice</span><span class="token punctuation">(</span><span class="token number">2</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">toLowerCase</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">,</span> value<span class="token punctuation">)</span>
      <span class="token punctuation">}</span>
        <span class="token comment">// 如果 新props 上面没有 对应的 key 就将旧的prosp的对应的key进行移除</span>
      <span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token operator">!</span><span class="token punctuation">(</span>key <span class="token keyword">in</span> newProps<span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
        el<span class="token punctuation">.</span><span class="token function">removeAttribute</span><span class="token punctuation">(</span>key<span class="token punctuation">)</span><span class="token punctuation">;</span>
      <span class="token punctuation">}</span>
    <span class="token punctuation">}</span>
</code></pre></div><h4 id="_3-最后处理-children"><a class="header-anchor" href="#_3-最后处理-children" aria-hidden="true">#</a> 3: 最后处理 children</h4><div class="language-javascript"><pre><code>    <span class="token comment">//处理children</span>
    <span class="token keyword">const</span> oldChildren <span class="token operator">=</span> n1<span class="token punctuation">.</span>children <span class="token operator">||</span> <span class="token punctuation">[</span><span class="token punctuation">]</span>
    <span class="token keyword">const</span> newChildren <span class="token operator">=</span> n2<span class="token punctuation">.</span>children <span class="token operator">||</span> <span class="token punctuation">[</span><span class="token punctuation">]</span>
    <span class="token comment">// 如果新vnode  的children 是字符串 类型  就直接进行赋值</span>
    <span class="token keyword">if</span><span class="token punctuation">(</span> <span class="token keyword">typeof</span> newChildren <span class="token operator">===</span> <span class="token string">&quot;string&quot;</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
      <span class="token comment">//  edge case 边界判断</span>
      <span class="token keyword">if</span><span class="token punctuation">(</span> <span class="token keyword">typeof</span> oldChildren <span class="token operator">===</span> <span class="token string">&quot;string&quot;</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
        <span class="token keyword">if</span> <span class="token punctuation">(</span> oldChildren <span class="token operator">!==</span> newChildren <span class="token punctuation">)</span> <span class="token punctuation">{</span>
          el<span class="token punctuation">.</span>textContent <span class="token operator">=</span> newChildren
        <span class="token punctuation">}</span>
      <span class="token punctuation">}</span> <span class="token keyword">else</span> <span class="token punctuation">{</span>
        el<span class="token punctuation">.</span>innerHTML <span class="token operator">=</span> newChildren
      <span class="token punctuation">}</span>
    <span class="token punctuation">}</span> <span class="token keyword">else</span> <span class="token punctuation">{</span>
      <span class="token comment">// 新vnode 是数组  旧vnode是字符串的情况</span>
      <span class="token keyword">if</span> <span class="token punctuation">(</span> <span class="token keyword">typeof</span> oldChildren <span class="token operator">===</span> <span class="token string">&quot;string&quot;</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
        el<span class="token punctuation">.</span>innerHTML <span class="token operator">=</span> <span class="token string">&quot;&quot;</span>
        newChildren<span class="token punctuation">.</span><span class="token function">forEach</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token parameter">item</span><span class="token punctuation">)</span> <span class="token operator">=&gt;</span> <span class="token punctuation">{</span>
          <span class="token function">mount</span><span class="token punctuation">(</span>item<span class="token punctuation">,</span> el<span class="token punctuation">)</span>
        <span class="token punctuation">}</span><span class="token punctuation">)</span>
      <span class="token punctuation">}</span> <span class="token keyword">else</span> <span class="token punctuation">{</span>
        <span class="token comment">//  都是数组的情况</span>
        <span class="token comment">// 对于有相同节点进行patch 操作</span>
        <span class="token comment">// 这里处理没有 key 的情况下</span>
        <span class="token comment">// 1 先取出 更短的长度进行遍历 进行diff算法</span>
        <span class="token keyword">const</span> commonLength <span class="token operator">=</span> Math<span class="token punctuation">.</span><span class="token function">min</span><span class="token punctuation">(</span>oldChildren<span class="token punctuation">.</span>length<span class="token punctuation">,</span> newChildren<span class="token punctuation">.</span>length<span class="token punctuation">)</span>
        <span class="token keyword">for</span><span class="token punctuation">(</span><span class="token keyword">let</span> i <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span> i <span class="token operator">&lt;</span> commonLength<span class="token punctuation">;</span> i <span class="token operator">++</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
          <span class="token comment">// 将公共 部分 进行 patch()</span>
          <span class="token function">patch</span><span class="token punctuation">(</span>oldChildren<span class="token punctuation">[</span>i<span class="token punctuation">]</span><span class="token punctuation">,</span> newChildren<span class="token punctuation">[</span>i<span class="token punctuation">]</span><span class="token punctuation">)</span>
        <span class="token punctuation">}</span>
        <span class="token comment">//  新的节点 长度大于 旧的长度 是将多余的部分进行挂载操作  mount()</span>
        <span class="token keyword">if</span><span class="token punctuation">(</span> newChildren<span class="token punctuation">.</span>length <span class="token operator">&gt;</span> oldChildren<span class="token punctuation">.</span>length<span class="token punctuation">)</span> <span class="token punctuation">{</span>
          newChildren<span class="token punctuation">.</span><span class="token function">slice</span><span class="token punctuation">(</span>oldChildren<span class="token punctuation">.</span>length<span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">forEach</span><span class="token punctuation">(</span><span class="token parameter">item</span> <span class="token operator">=&gt;</span> <span class="token punctuation">{</span>
            <span class="token function">mount</span><span class="token punctuation">(</span>item<span class="token punctuation">,</span> el<span class="token punctuation">)</span>
          <span class="token punctuation">}</span><span class="token punctuation">)</span>
        <span class="token punctuation">}</span>
        <span class="token comment">//  新的节点 小于旧的节点长度,  将 旧的节点 进行移除操作  removechild()</span>
        <span class="token keyword">if</span><span class="token punctuation">(</span> newChildren<span class="token punctuation">.</span>length <span class="token operator">&lt;</span> oldChildren<span class="token punctuation">.</span>length<span class="token punctuation">)</span> <span class="token punctuation">{</span>
          oldChildren<span class="token punctuation">.</span><span class="token function">slice</span><span class="token punctuation">(</span>newChidlren<span class="token punctuation">.</span>length<span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">forEach</span><span class="token punctuation">(</span><span class="token parameter">item</span> <span class="token operator">=&gt;</span> <span class="token punctuation">{</span>
            el<span class="token punctuation">.</span><span class="token function">removeChild</span><span class="token punctuation">(</span>item<span class="token punctuation">.</span>el<span class="token punctuation">)</span>
          <span class="token punctuation">}</span><span class="token punctuation">)</span>
        <span class="token punctuation">}</span>
      <span class="token punctuation">}</span>
    <span class="token punctuation">}</span>

  <span class="token punctuation">}</span>
<span class="token punctuation">}</span>
</code></pre></div><h4 id="_4-patch-函数的总结"><a class="header-anchor" href="#_4-patch-函数的总结" aria-hidden="true">#</a> 4: patch 函数的总结</h4><p>​ vue 中具体的实现考虑了很多情况,这里只是学习了其中的基本思想,(只考虑了的简单的)</p><p>patch()主要是要传入两个 VNode 对我们的节点进行 diff 算法,然后通过得出不一样的地方进行 DOM 对应操作</p><h2 id="响应式系统"><a class="header-anchor" href="#响应式系统" aria-hidden="true">#</a> 响应式系统</h2><h3 id="响应式的思想"><a class="header-anchor" href="#响应式的思想" aria-hidden="true">#</a> 响应式的思想::</h3><p>​ 数据如果在函数中被更改 那么每当数据更改时都要手动触发这些函数, 我们不希望每次手动做这些</p><p>具体的实现, 创建一个 Deps 容器收集 所有使用到 变化数据的 地方 (也就是收集依赖) 这个 Dep 类里面有收集依赖的方法以及执行 依赖函数的方法,</p><p>当我们的函数获取我们的响应式对象中的数据的时候 将这个函数 添加到我们设置好的数据结构;</p><p>当数据变化的时候 所有使用到这个数据的方法 就会自动执行一次</p><p>难点在于如何自动收集依赖?. 如何当数据变化 自动执行这些依赖函数?</p><div class="language-javascript"><pre><code><span class="token comment">// 定义一个Dep 类</span>
<span class="token keyword">class</span> <span class="token class-name">Dep</span> <span class="token punctuation">{</span>
  <span class="token function">constructor</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
    <span class="token comment">// 给每一个通过Dep类创建的对象 添加一个订阅者的集合</span>
    <span class="token comment">//  将 使用到数据的 函数(这里方便理解就设置为函数) 收集到这个集合里面</span>
    <span class="token comment">//  set 中元素不会重复, 保证 函数不会重复</span>
    <span class="token keyword">this</span><span class="token punctuation">.</span>subscribers <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">Set</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
  <span class="token punctuation">}</span>
  <span class="token comment">//  收集 副作用 方法</span>
  <span class="token function">depend</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
    <span class="token keyword">if</span> <span class="token punctuation">(</span>activeEffect<span class="token punctuation">)</span> <span class="token punctuation">{</span>
      <span class="token comment">//  集合中 添加对象使用 .add</span>
      <span class="token keyword">this</span><span class="token punctuation">.</span>subscribers<span class="token punctuation">.</span><span class="token function">add</span><span class="token punctuation">(</span>activeEffect<span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token punctuation">}</span>
  <span class="token punctuation">}</span>
  <span class="token comment">//  执行 这些副作用 方法</span>
  <span class="token function">notify</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
    <span class="token keyword">this</span><span class="token punctuation">.</span>subscribers<span class="token punctuation">.</span><span class="token function">forEach</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token parameter">effect</span><span class="token punctuation">)</span> <span class="token operator">=&gt;</span> <span class="token punctuation">{</span>
      <span class="token function">effect</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
  <span class="token punctuation">}</span>
<span class="token punctuation">}</span>
<span class="token keyword">let</span> activeEffect <span class="token operator">=</span> <span class="token keyword">null</span><span class="token punctuation">;</span>
<span class="token keyword">function</span> <span class="token function">watchEffect</span><span class="token punctuation">(</span><span class="token parameter">effect</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
  activeEffect <span class="token operator">=</span> effect<span class="token punctuation">;</span>
  <span class="token comment">//  第一次就要执行一次 所有调用依赖的方法</span>
  <span class="token function">effect</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
  activeEffect <span class="token operator">=</span> <span class="token keyword">null</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>

<span class="token comment">// 设置 数据结构的最外层</span>
<span class="token comment">//  map({key: value})  map 里面是一个个键值对   key 必须是 字符串</span>
<span class="token comment">//  weakMap({key(对象): value})  key 必须是一个对象 ,弱引用</span>
<span class="token keyword">const</span> targetMap <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">WeakMap</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token comment">//  根据 传进来 的 target, key  返回dep</span>
<span class="token keyword">function</span> <span class="token function">getDep</span><span class="token punctuation">(</span><span class="token parameter">target<span class="token punctuation">,</span> key</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
  <span class="token comment">// 将传进来的 target对象  取出来相应的map 对象 保存value</span>
  <span class="token keyword">let</span> depsMap <span class="token operator">=</span> targetMap<span class="token punctuation">.</span><span class="token function">get</span><span class="token punctuation">(</span>target<span class="token punctuation">)</span><span class="token punctuation">;</span>
  <span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token operator">!</span>depsMap<span class="token punctuation">)</span> <span class="token punctuation">{</span>
    depsMap <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">Map</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token comment">//  形成我们 想要的数据结构     [{info}]</span>
    targetMap<span class="token punctuation">.</span><span class="token function">set</span><span class="token punctuation">(</span>target<span class="token punctuation">,</span> depsMap<span class="token punctuation">)</span><span class="token punctuation">;</span>
  <span class="token punctuation">}</span>
  <span class="token comment">// 取出 具体的 dep 对象</span>
  <span class="token keyword">let</span> dep <span class="token operator">=</span> depsMap<span class="token punctuation">.</span><span class="token function">get</span><span class="token punctuation">(</span>key<span class="token punctuation">)</span><span class="token punctuation">;</span>
  <span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token operator">!</span>dep<span class="token punctuation">)</span> <span class="token punctuation">{</span>
    dep <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">Dep</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
    depsMap<span class="token punctuation">.</span><span class="token function">set</span><span class="token punctuation">(</span>key<span class="token punctuation">,</span> dep<span class="token punctuation">)</span><span class="token punctuation">;</span>
  <span class="token punctuation">}</span>
  <span class="token keyword">return</span> dep<span class="token punctuation">;</span>
<span class="token punctuation">}</span>

<span class="token comment">//  vue3 中 对 raw 的数据劫持</span>
<span class="token comment">// reactive() 函数中 要对传进来的 raw 对象进行数据劫持</span>
<span class="token keyword">function</span> <span class="token function">reactive</span><span class="token punctuation">(</span><span class="token parameter">raw</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
  <span class="token keyword">return</span> <span class="token keyword">new</span> <span class="token class-name">Proxy</span><span class="token punctuation">(</span>raw<span class="token punctuation">,</span> <span class="token punctuation">{</span>
    <span class="token comment">//  获取数据的时候 会调用 get()</span>
    <span class="token function">get</span><span class="token punctuation">(</span>target<span class="token punctuation">,</span> key<span class="token punctuation">)</span> <span class="token punctuation">{</span>
      <span class="token keyword">const</span> dep <span class="token operator">=</span> <span class="token function">getDep</span><span class="token punctuation">(</span>target<span class="token punctuation">,</span> key<span class="token punctuation">)</span><span class="token punctuation">;</span>
      dep<span class="token punctuation">.</span><span class="token function">depend</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
      <span class="token keyword">return</span> target<span class="token punctuation">[</span>key<span class="token punctuation">]</span><span class="token punctuation">;</span>
    <span class="token punctuation">}</span><span class="token punctuation">,</span>
    <span class="token comment">//  设置数据的时候会 调用 set()</span>
    <span class="token function">set</span><span class="token punctuation">(</span>target<span class="token punctuation">,</span> key<span class="token punctuation">,</span> newValue<span class="token punctuation">)</span> <span class="token punctuation">{</span>
      <span class="token keyword">const</span> dep <span class="token operator">=</span> <span class="token function">getDep</span><span class="token punctuation">(</span>target<span class="token punctuation">,</span> key<span class="token punctuation">)</span><span class="token punctuation">;</span>
      target<span class="token punctuation">[</span>key<span class="token punctuation">]</span> <span class="token operator">=</span> newValue<span class="token punctuation">;</span>
      dep<span class="token punctuation">.</span><span class="token function">notify</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token punctuation">}</span><span class="token punctuation">,</span>
  <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>

<span class="token comment">//</span>
<span class="token keyword">const</span> proxy <span class="token operator">=</span> <span class="token function">reactive</span><span class="token punctuation">(</span><span class="token punctuation">{</span> name<span class="token operator">:</span> <span class="token string">&quot;Eason&quot;</span> <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
proxy<span class="token punctuation">.</span>name <span class="token operator">=</span> <span class="token string">&quot;信心花舍&quot;</span><span class="token punctuation">;</span>

<span class="token keyword">const</span> info <span class="token operator">=</span> <span class="token function">reactive</span><span class="token punctuation">(</span><span class="token punctuation">{</span> age<span class="token operator">:</span> <span class="token number">1974</span><span class="token punctuation">,</span> name<span class="token operator">:</span> <span class="token string">&quot;Eason&quot;</span> <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token keyword">const</span> song <span class="token operator">=</span> <span class="token function">reactive</span><span class="token punctuation">(</span><span class="token punctuation">{</span> title<span class="token operator">:</span> <span class="token string">&quot;无条件&quot;</span> <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span>

<span class="token function">watchEffect</span><span class="token punctuation">(</span><span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
  console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">&quot;effect1&quot;</span><span class="token punctuation">,</span> info<span class="token punctuation">.</span>age <span class="token operator">-</span> <span class="token number">100</span><span class="token punctuation">,</span> info<span class="token punctuation">.</span>name<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span>

<span class="token function">watchEffect</span><span class="token punctuation">(</span><span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
  console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">&quot;effect2&quot;</span><span class="token punctuation">,</span> <span class="token number">2021</span> <span class="token operator">-</span> info<span class="token punctuation">.</span>age <span class="token operator">+</span> <span class="token number">3</span><span class="token punctuation">,</span> info<span class="token punctuation">.</span>name<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span>

<span class="token function">watchEffect</span><span class="token punctuation">(</span><span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
  console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">&quot;effect3&quot;</span><span class="token punctuation">,</span> song<span class="token punctuation">.</span>title<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span>

<span class="token function">setTimeout</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">=&gt;</span> <span class="token punctuation">{</span>
  song<span class="token punctuation">.</span>title <span class="token operator">=</span> <span class="token string">&quot;沙龙&quot;</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span><span class="token punctuation">,</span> <span class="token number">3000</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
</code></pre></div><h2 id="vue2-跟-vue3-的响应式区别"><a class="header-anchor" href="#vue2-跟-vue3-的响应式区别" aria-hidden="true">#</a> Vue2 跟 Vue3 的响应式区别</h2><h3 id="object-definepropery"><a class="header-anchor" href="#object-definepropery" aria-hidden="true">#</a> object.definePropery</h3><ul><li>object.definePropery 是劫持对象的属性</li><li>对指定的 key 生成 getter/setter 以进行变化追踪，那么如果这个 key 一开始不存在我们定义的对象上，响应式系统就无能为力了，所以在 Vue2 中无法检测对象的 property 的添加或移除。而对于这个缺陷，Vue2 提供了 <code>vm.$set</code> 和全局的 <code>Vue.set</code> API 让我们能够向对象添加响应式的 property</li><li>从数组的角度来说，当我们直接利用索引设置一个数组项时，或者当我们修改数组长度时，Vue2 的响应式系统都不能监听到变化，解决的方法也如上，使用上面提及的 2 个 api。</li></ul><h3 id="proxy"><a class="header-anchor" href="#proxy" aria-hidden="true">#</a> Proxy</h3><ul><li>Proxy 劫持的整个对象</li><li>ES6 的新特性 Proxy 面前通通都是不存在的，Proxy 对象能够利用 handler 陷阱在 get、set 时捕获到任何变动，也能监听对数组索引的改动以及 数组 length 的改动。</li><li>在 Vue3 中，通过 track 的处理器函数来收集依赖，通过 trigger 的处理器函数来派发更新，每个依赖的使用都会被包裹到一个副作用（effect）函数中，而派发更新后就会执行副作用函数，这样依赖处的值就被更新了</li></ul><h2 id="响应式基础-reactive-的核心源码"><a class="header-anchor" href="#响应式基础-reactive-的核心源码" aria-hidden="true">#</a> 响应式基础 reactive 的核心源码</h2><div class="language-javascript"><pre><code><span class="token comment">// 定义一个Dep 类</span>
<span class="token keyword">class</span> <span class="token class-name">Dep</span> <span class="token punctuation">{</span>
  <span class="token function">constructor</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
    <span class="token comment">// 给每一个通过Dep类创建的对象 添加一个订阅者的集合</span>
    <span class="token comment">//  将 使用到数据的 函数(这里方便理解就设置为函数) 收集到这个集合里面</span>
    <span class="token comment">//  set 中元素不会重复, 保证 函数不会重复</span>
    <span class="token keyword">this</span><span class="token punctuation">.</span>subscribers <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">Set</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
  <span class="token punctuation">}</span>
  <span class="token comment">//  收集 副作用 方法</span>
  <span class="token function">depend</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
    <span class="token keyword">if</span> <span class="token punctuation">(</span>activeEffect<span class="token punctuation">)</span> <span class="token punctuation">{</span>
      <span class="token comment">//  集合中 添加对象使用 .add</span>
      <span class="token keyword">this</span><span class="token punctuation">.</span>subscribers<span class="token punctuation">.</span><span class="token function">add</span><span class="token punctuation">(</span>activeEffect<span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token punctuation">}</span>
  <span class="token punctuation">}</span>
  <span class="token comment">//  执行 这些副作用 方法</span>
  <span class="token function">notify</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
    <span class="token keyword">this</span><span class="token punctuation">.</span>subscribers<span class="token punctuation">.</span><span class="token function">forEach</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token parameter">effect</span><span class="token punctuation">)</span> <span class="token operator">=&gt;</span> <span class="token punctuation">{</span>
      <span class="token function">effect</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
  <span class="token punctuation">}</span>
<span class="token punctuation">}</span>

<span class="token keyword">let</span> activeEffect <span class="token operator">=</span> <span class="token keyword">null</span><span class="token punctuation">;</span>
<span class="token keyword">function</span> <span class="token function">watchEffect</span><span class="token punctuation">(</span><span class="token parameter">effect</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
  activeEffect <span class="token operator">=</span> effect<span class="token punctuation">;</span>
  <span class="token comment">//  第一次就要执行一次 所有调用依赖的方法</span>
  <span class="token function">effect</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
  activeEffect <span class="token operator">=</span> <span class="token keyword">null</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>

<span class="token comment">// 设置 数据结构的最外层</span>
<span class="token comment">//  map({key: value})  map 里面是一个个键值对   key 必须是 字符串</span>
<span class="token comment">//  weakMap({key(对象): value})  key 必须是一个对象 ,弱引用</span>
<span class="token keyword">const</span> targetMap <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">WeakMap</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token comment">//  根据 传进来 的 target, key  返回dep</span>
<span class="token keyword">function</span> <span class="token function">getDep</span><span class="token punctuation">(</span><span class="token parameter">target<span class="token punctuation">,</span> key</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
  <span class="token comment">// 将传进来的 target对象  取出来相应的map 对象 保存value</span>
  <span class="token keyword">let</span> depsMap <span class="token operator">=</span> targetMap<span class="token punctuation">.</span><span class="token function">get</span><span class="token punctuation">(</span>target<span class="token punctuation">)</span><span class="token punctuation">;</span>
  <span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token operator">!</span>depsMap<span class="token punctuation">)</span> <span class="token punctuation">{</span>
    depsMap <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">Map</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token comment">//  形成我们 想要的数据结构     [{info}]</span>
    targetMap<span class="token punctuation">.</span><span class="token function">set</span><span class="token punctuation">(</span>target<span class="token punctuation">,</span> depsMap<span class="token punctuation">)</span><span class="token punctuation">;</span>
  <span class="token punctuation">}</span>
  <span class="token comment">// 取出 具体的 dep 对象</span>
  <span class="token keyword">let</span> dep <span class="token operator">=</span> depsMap<span class="token punctuation">.</span><span class="token function">get</span><span class="token punctuation">(</span>key<span class="token punctuation">)</span><span class="token punctuation">;</span>
  <span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token operator">!</span>dep<span class="token punctuation">)</span> <span class="token punctuation">{</span>
    dep <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">Dep</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
    depsMap<span class="token punctuation">.</span><span class="token function">set</span><span class="token punctuation">(</span>key<span class="token punctuation">,</span> dep<span class="token punctuation">)</span><span class="token punctuation">;</span>
  <span class="token punctuation">}</span>
  <span class="token keyword">return</span> dep<span class="token punctuation">;</span>
<span class="token punctuation">}</span>

<span class="token comment">//  vue3 中 对 raw 的数据劫持</span>
<span class="token comment">// reactive() 函数中 要对传进来的 raw 对象进行数据劫持</span>
<span class="token keyword">function</span> <span class="token function">reactive</span><span class="token punctuation">(</span><span class="token parameter">raw</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
  <span class="token keyword">return</span> <span class="token keyword">new</span> <span class="token class-name">Proxy</span><span class="token punctuation">(</span>raw<span class="token punctuation">,</span> <span class="token punctuation">{</span>
    <span class="token comment">//  获取数据的时候 会调用 get()</span>
    <span class="token function">get</span><span class="token punctuation">(</span>target<span class="token punctuation">,</span> key<span class="token punctuation">)</span> <span class="token punctuation">{</span>
      <span class="token keyword">const</span> dep <span class="token operator">=</span> <span class="token function">getDep</span><span class="token punctuation">(</span>target<span class="token punctuation">,</span> key<span class="token punctuation">)</span><span class="token punctuation">;</span>
      dep<span class="token punctuation">.</span><span class="token function">depend</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
      <span class="token keyword">return</span> target<span class="token punctuation">[</span>key<span class="token punctuation">]</span><span class="token punctuation">;</span>
    <span class="token punctuation">}</span><span class="token punctuation">,</span>
    <span class="token comment">//  设置数据的时候会 调用 set()</span>
    <span class="token function">set</span><span class="token punctuation">(</span>target<span class="token punctuation">,</span> key<span class="token punctuation">,</span> newValue<span class="token punctuation">)</span> <span class="token punctuation">{</span>
      <span class="token keyword">const</span> dep <span class="token operator">=</span> <span class="token function">getDep</span><span class="token punctuation">(</span>target<span class="token punctuation">,</span> key<span class="token punctuation">)</span><span class="token punctuation">;</span>
      target<span class="token punctuation">[</span>key<span class="token punctuation">]</span> <span class="token operator">=</span> newValue<span class="token punctuation">;</span>
      dep<span class="token punctuation">.</span><span class="token function">notify</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token punctuation">}</span><span class="token punctuation">,</span>
  <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>

<span class="token comment">//</span>
<span class="token keyword">const</span> proxy <span class="token operator">=</span> <span class="token function">reactive</span><span class="token punctuation">(</span><span class="token punctuation">{</span> name<span class="token operator">:</span> <span class="token string">&quot;Eason&quot;</span> <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
proxy<span class="token punctuation">.</span>name <span class="token operator">=</span> <span class="token string">&quot;信心花舍&quot;</span><span class="token punctuation">;</span>

<span class="token keyword">const</span> info <span class="token operator">=</span> <span class="token function">reactive</span><span class="token punctuation">(</span><span class="token punctuation">{</span> age<span class="token operator">:</span> <span class="token number">1974</span><span class="token punctuation">,</span> name<span class="token operator">:</span> <span class="token string">&quot;Eason&quot;</span> <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token keyword">const</span> song <span class="token operator">=</span> <span class="token function">reactive</span><span class="token punctuation">(</span><span class="token punctuation">{</span> title<span class="token operator">:</span> <span class="token string">&quot;无条件&quot;</span> <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span>

<span class="token function">watchEffect</span><span class="token punctuation">(</span><span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
  console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">&quot;effect1&quot;</span><span class="token punctuation">,</span> info<span class="token punctuation">.</span>age <span class="token operator">-</span> <span class="token number">100</span><span class="token punctuation">,</span> info<span class="token punctuation">.</span>name<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span>

<span class="token function">watchEffect</span><span class="token punctuation">(</span><span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
  console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">&quot;effect2&quot;</span><span class="token punctuation">,</span> <span class="token number">2021</span> <span class="token operator">-</span> info<span class="token punctuation">.</span>age <span class="token operator">+</span> <span class="token number">3</span><span class="token punctuation">,</span> info<span class="token punctuation">.</span>name<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span>

<span class="token function">watchEffect</span><span class="token punctuation">(</span><span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
  console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">&quot;effect3&quot;</span><span class="token punctuation">,</span> song<span class="token punctuation">.</span>title<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span>

<span class="token function">setTimeout</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">=&gt;</span> <span class="token punctuation">{</span>
  song<span class="token punctuation">.</span>title <span class="token operator">=</span> <span class="token string">&quot;沙龙&quot;</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span><span class="token punctuation">,</span> <span class="token number">3000</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
</code></pre></div></div></div><footer class="page-footer" data-v-7eddb2c4 data-v-fb8d84c6><div class="edit" data-v-fb8d84c6><div class="edit-link" data-v-fb8d84c6 data-v-1ed99556><!----></div></div><div class="updated" data-v-fb8d84c6><!----></div></footer><div class="next-and-prev-link" data-v-7eddb2c4 data-v-38ede35f><div class="container" data-v-38ede35f><div class="prev" data-v-38ede35f><a class="link" href="/interview/Vue/Router" data-v-38ede35f><svg xmlns="http://www.w3.org/2000/svg" viewbox="0 0 24 24" class="icon icon-prev" data-v-38ede35f><path d="M19,11H7.4l5.3-5.3c0.4-0.4,0.4-1,0-1.4s-1-0.4-1.4,0l-7,7c-0.1,0.1-0.2,0.2-0.2,0.3c-0.1,0.2-0.1,0.5,0,0.8c0.1,0.1,0.1,0.2,0.2,0.3l7,7c0.2,0.2,0.5,0.3,0.7,0.3s0.5-0.1,0.7-0.3c0.4-0.4,0.4-1,0-1.4L7.4,13H19c0.6,0,1-0.4,1-1S19.6,11,19,11z"></path></svg><span class="text" data-v-38ede35f>Router4.x</span></a></div><div class="next" data-v-38ede35f><a class="link" href="/interview/Vue/source/Watch" data-v-38ede35f><span class="text" data-v-38ede35f>Watch</span><svg xmlns="http://www.w3.org/2000/svg" viewbox="0 0 24 24" class="icon icon-next" data-v-38ede35f><path d="M19.9,12.4c0.1-0.2,0.1-0.5,0-0.8c-0.1-0.1-0.1-0.2-0.2-0.3l-7-7c-0.4-0.4-1-0.4-1.4,0s-0.4,1,0,1.4l5.3,5.3H5c-0.6,0-1,0.4-1,1s0.4,1,1,1h11.6l-5.3,5.3c-0.4,0.4-0.4,1,0,1.4c0.2,0.2,0.5,0.3,0.7,0.3s0.5-0.1,0.7-0.3l7-7C19.8,12.6,19.9,12.5,19.9,12.4z"></path></svg></a></div></div></div><!--[--><!--]--></div></main></div><!----><!--]--></div>
    <script>__VP_HASH_MAP__ = JSON.parse("{\"index.md\":\"992e2bc4\",\"css_advanced.md\":\"157298f3\",\"css_index.md\":\"0df1ef28\",\"browser_advanced.md\":\"a7a79457\",\"browser_index.md\":\"9938c247\",\"browser_plugin.md\":\"fd27046d\",\"git_index.md\":\"fb33a92a\",\"html_advanced.md\":\"599ad3d5\",\"html_index.md\":\"c94736b6\",\"interview_index.md\":\"07dc8acc\",\"interview_two.md\":\"0ca812f6\",\"javascript_advanced.md\":\"5c434e6d\",\"javascript_index.md\":\"d996a3fc\",\"jenkins_index.md\":\"3068e232\",\"myself_index.md\":\"340fc837\",\"myself_one.md\":\"31202d59\",\"myself_pre.md\":\"aa93248e\",\"network_index.md\":\"7251e8b9\",\"network_security.md\":\"d11dae3c\",\"node_index.md\":\"e0b22fc7\",\"node_pit.md\":\"a1502c64\",\"npm_index.md\":\"59b033b6\",\"pit_index.md\":\"603d46aa\",\"solution_index.md\":\"987aa705\",\"typescript_advanced.md\":\"431b8bba\",\"typescript_combat.md\":\"60c9a8a2\",\"typescript_index.md\":\"bd88b5a2\",\"vite_index.md\":\"d6838c03\",\"vite_optimize.md\":\"49f1bb24\",\"vue_index.md\":\"380ec221\",\"vue_reactive.md\":\"206c8e46\",\"vue_router.md\":\"0d556c25\",\"vue_source.md\":\"592e192a\",\"vue_vuex.md\":\"032502ef\",\"webpack_advanced.md\":\"ae6c63b7\",\"webpack_common.md\":\"141deb7a\",\"webpack_custom.md\":\"4827ebf8\",\"webpack_index.md\":\"49f185a6\",\"webpack_optimize.md\":\"545698f9\",\"vue_source_index.md\":\"1c12bc29\",\"vue_source_nexttick.md\":\"4533a28b\",\"vue_source_watch.md\":\"0e7342fc\"}")</script>
    <script type="module" async src="/interview/assets/app.49accf37.js"></script>
  </body>
</html>